package org.andromeo;

import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.andromeo.connectionapi.MessageListProcessor;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Messenger;
import android.os.RemoteException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MessagelistActivity extends ListActivity {
	/** Called when the activity is first created. */
	ListView listview = null;

	private GRSession grsession;
	ArrayAdapter<Message> messageAdapter;
	MessageListProcessor messageListProcessor;
	MessagelistActivity thisListActivity = this;

	ProgressDialog mProgDialog;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		grsession = ((ARApplication) getApplication()).getGrsession();

		// setContentView(R.layout.friendlist);
		// listview = (ListView) findViewById(R.id.friendlistview);

		listview = getListView();

		/**
		 * create message list processor (extracts the data from gayromeo
		 * website)
		 * 
		 * generate list adapter and assign with listview
		 */
		messageAdapter = new MessageListAdapter(MessagelistActivity.this,
				android.R.layout.simple_list_item_1, new Vector<Message>());

		listview.setAdapter(messageAdapter);

		/**
		 * set background
		 */
		listview.setBackgroundDrawable((this.getResources()
				.getDrawable(R.drawable.solid_blue_bg)));
		listview.setCacheColorHint(this.getResources().getColor(
				R.drawable.color_transparent));

		/**
		 * build progess dialog
		 */
		mProgDialog = new ProgressDialog(MessagelistActivity.this);
		mProgDialog.setTitle(R.string.working);
		mProgDialog.setMessage(getString(R.string.pull_messagelist));
		mProgDialog.setIndeterminate(true);
		mProgDialog.setCancelable(false);

	}

	@Override
	protected void onStart() {
		super.onStart();
		doBindService();
		mHandler.post(messagelistExtractor);
	}

	@Override
	protected void onRestart() {
		super.onRestart();
		messageAdapter.notifyDataSetChanged();
	}

	/**
	 * called when activity is visible again helps against refresh problems
	 */
	@Override
	protected void onResume() {
		super.onResume();
		messageAdapter.notifyDataSetChanged();
	}

	@Override
	protected void onStop() {
		doUnbindService();
		super.onStop();
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		// TODO Auto-generated method stub
		super.onListItemClick(l, v, position, id);

		Intent msgintent = new Intent(Intent.ACTION_SENDTO);
		msgintent.setClassName(WriteMessageActivity.class.getPackage()
				.getName(), WriteMessageActivity.class.getName());

		msgintent.putExtra(WriteMessageActivity.KEY_USERID, messageAdapter
				.getItem(position).getMessagePartner().getUserID());
		msgintent.putExtra(WriteMessageActivity.KEY_PREVIOUSMESSAGE,
				messageAdapter.getItem(position).getPreviewText());
		msgintent.putExtra(WriteMessageActivity.KEY_PREVIOUSMESSAGEID,
				messageAdapter.getItem(position).getMessageID());

		startActivityForResult(msgintent, 0);
	}

	Handler mHandler = new Handler();

	private int messageExtractionInterval = 2 * 60 * 1000;
	private long nextMessageExtractionTime;

	/*
	 * get the messages a
	 */
	private Runnable messagelistExtractor = new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			new GetMessageListTask().execute(grsession);
		}

	};

	/*
	 * Get messages using AsyncTask-class, should improve UI-Speed
	 */
	private class GetMessageListTask extends
			AsyncTask<GRSession, Integer, Integer> {

		List<Message> worklist;

		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			super.onPreExecute();
			if (messageAdapter.isEmpty())
				mProgDialog.show();
			else
				Toast.makeText(
						MessagelistActivity.this,
						MessagelistActivity.this
								.getString(R.string.pull_messagelist),
						Toast.LENGTH_LONG).show();
		}

		@Override
		protected Integer doInBackground(GRSession... params) {
			try {
				worklist = grsession.getMessageFactory().getReceivedMsgList();
				// worklist =
				// MessageListProcessor.getReceivedMessages(grsession);
				// worklist = messageListProcessor.getReceivedMessages();
				return 0;
			} catch (Exception e) {
				e.printStackTrace();
				return 99;
			}
		}

		@Override
		protected void onPostExecute(Integer result) {

			if (result == 0) {
				for (Iterator<Message> it = worklist.iterator(); it.hasNext();) {
					Message msg = it.next();

					if (messageAdapter.getPosition(msg) < 0)
						messageAdapter.add(msg);
				}

				messageAdapter.sort(Message.getCompSortByIdDescending());

			}

			mProgDialog.dismiss();
			messageAdapter.notifyDataSetChanged();
		}
	}

	/*
	 * 
	 */

	public static final SimpleDateFormat sdf = new SimpleDateFormat(
			"dd.MM. HH:mm");

	private class MessageListAdapter extends ArrayAdapter<Message> {

		public MessageListAdapter(Context context, int textViewResourceId,
				List<Message> objects) {
			super(context, textViewResourceId, objects);
			// TODO Auto-generated constructor stub
		}

		public View getView(int position, View convertView, ViewGroup parent) {

			/*
			 * User item to display
			 */
			Message vMessage;

			/**
			 * Build 'n' connect to UI-Items
			 */
			ImageView imageItemView;
			TextView usernameItemView;
			TextView statusItemView;
			TextView messageTextItemView;
			TextView dateTimeTextItemView;
			View v = convertView;

			if (v == null) {
				LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				v = vi.inflate(R.layout.messagelistitem, null);

			}
			imageItemView = (ImageView) v
					.findViewById(R.id.messageListItemIcon);
			usernameItemView = (TextView) v
					.findViewById(R.id.messageListItemUserName);
			statusItemView = (TextView) v
					.findViewById(R.id.messageListItemOnlineStatus);
			messageTextItemView = (TextView) v
					.findViewById(R.id.messageListItemText);
			dateTimeTextItemView = (TextView) v
					.findViewById(R.id.messageListDateTime);
			vMessage = this.getItem(position);

			/**
			 * Get data to display
			 */
			String vUsername = "USERNAME";
			String vOnlineStatus = "ONLINESTATUS";
			boolean vNewMessage = false;
			boolean vSavedMessage = false;
			String vMessageText = "TEXT";

			if (vMessage != null) {
				if (vMessage.getMessagePartner() != null) {
					vUsername = vMessage.getMessagePartner().getUserName();
					vOnlineStatus = vMessage.getMessagePartner()
							.getOnlineStatus();
				}
				vNewMessage = vMessage.isMarkNewMessage();
				vSavedMessage = vMessage.isMarkSavedMessage();
				vMessageText = vMessage.getPreviewText();
			}

			/**
			 * insert data to item
			 */
			usernameItemView.setText(vUsername);
			statusItemView.setText(vOnlineStatus);
			messageTextItemView.setText(vMessageText);
			if (vNewMessage) {
				if (vMessage.getHasAttachments()) {
					imageItemView
							.setImageResource(R.drawable.andromeo_msg_attach_new);
				} else {
					imageItemView.setImageResource(R.drawable.andromeo_msg_new);
				}
			} else if (vSavedMessage) {
				if (vMessage.getHasAttachments()) {
					imageItemView
							.setImageResource(R.drawable.andromeo_msg_attach_saved);
				} else {
					imageItemView
							.setImageResource(R.drawable.andromeo_msg_saved);
				}
			} else {
				if (vMessage.getHasAttachments()) {
					imageItemView
							.setImageResource(R.drawable.andromeo_msg_attach);
				} else {
					imageItemView.setImageResource(R.drawable.andromeo_msg_old);
				}
			}

			// add date and time
			if (vMessage.getMessageTimestamp() != null) {
				dateTimeTextItemView.setText(sdf.format(vMessage
						.getMessageTimestamp()));
			}
			return v;
		}
	};
	
	protected void onDestroy() {
		super.onDestroy();
		mHandler.removeCallbacks(messagelistExtractor);
	};

	// Some code for handling

	boolean mIsBound = false;

	// remote messenger
	Messenger rMessenger = null;

	/**
	 * This handler receives a message when the underlying dataset has changed
	 */
	private Handler incomingHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			if (msg.what == HeartbeatService.ANDROIDMSG_DATASET_CHANGED) {
				mHandler.post(messagelistExtractor);
			}
		};
	};

	private android.os.Messenger messenger = new android.os.Messenger(
			incomingHandler);

	private ServiceConnection servConn = new ServiceConnection() {

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			try {
				rMessenger = new Messenger(service);
				android.os.Message amsg = android.os.Message.obtain(
						incomingHandler,
						HeartbeatService.ANDROIDMSG_REGISTER_HANDLER);
				amsg.replyTo = messenger;
				rMessenger.send(amsg);
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// currently does nothing
		}

	};

	void doBindService() {
		// bindService must be called via getApplicationcontext, otherwise no
		// bind will be executed!
		mIsBound = getApplicationContext().bindService(
				new Intent(this, HeartbeatService.class), servConn, 0);

	}

	void doUnbindService() {
		if (mIsBound) {
			// If we have received the service, and hence registered with
			// it, then now is the time to unregister.
			if (rMessenger != null) {
				try {
					android.os.Message msg = android.os.Message.obtain(null,
							HeartbeatService.ANDROIDMSG_UNREGISTER_HANDLER);
					msg.replyTo = messenger;
					rMessenger.send(msg);
				} catch (RemoteException e) {
					// There is nothing special we need to do if the service
					// has crashed.
				}
			}

			// Detach our existing connection.
			getApplicationContext().unbindService(servConn);
			mIsBound = false;
		}
	}

}
